日期：2023/7/29 出题人：\href{https://github.com/dynilath}{Da'Inihlus}\\

要求实现 \textbf{scope\_guard} 类型（即支持传入任意可调用类型 , 析构的时候同时调用 ）。

\begin{minted}[mathescape,	
    linenos,
    numbersep=5pt,
    gobble=2,
    frame=lines,
    framesep=2mm]{c++}
    #include <cstdio>
    #include <cassert>
    
    #include <stdexcept>
    #include <iostream>
    #include <functional>
    
    struct X {
        X() { puts("X()"); }
        X(const X&) { puts("X(const X&)"); }
        X(X&&) noexcept { puts("X(X&&)"); }
        ~X() { puts("~X()"); }
    };
    
    int main() {
        {
            // scope_guard的作用之一，是让各种C风格指针接口作为局部变量时也能得到RAII支持
            // 这也是本题的基础要求
            FILE * fp = nullptr;
            try{
                fp = fopen("test.txt","a");
                auto guard = scope_guard([&] {
                    fclose(fp);
                    fp = nullptr;
                });
    
                throw std::runtime_error{"Test"};
            } catch(std::exception & e){
                puts(e.what());
            }
            assert(fp == nullptr);
        }
        puts("----------");
        {
            // 附加要求1，支持函数对象调用
            struct Test {
                void operator()(X* x) {
                    delete x;
                }
            } t;
            auto x = new X{};
            auto guard = scope_guard(t, x);
        }
        puts("----------");
        {
            // 附加要求2，支持成员函数和std::ref
            auto x = new X{};
            {
                struct Test {
                    void f(X*& px) {
                        delete px;
                        px = nullptr;
                    }
                } t;
                auto guard = scope_guard{&Test::f, &t, std::ref(x)};
            }
            assert(x == nullptr);
        }
    }
\end{minted}

\begin{tcolorbox}[title = {要求运行结果},
        fonttitle = \bfseries, fontupper = \sffamily, fontlower = \itshape]
    Test        \\
    ----------  \\
    X()         \\
    ~X()        \\
    ----------  \\
    X()         \\
    ~X()
\end{tcolorbox}

\begin{itemize}
    \item \textbf{难度}： \hardscore{4} \\
    \textbf{提示}：C++11 形参包，成员指针，完美转发，std::tuple，std::apply，C++17 类推导指引，std::invoke，std::function
\end{itemize}